#import "nnet.h"

+ (int)numFuncs
{
	/* une fonction par output */
	return NB_OUTPUT ;
}

+ (char *)funcName:(int)functionNumber
{
	return fonction_name[functionNumber] ;
}

- execute:(void *)stack numberOfParams:(int)num sheet:(void *)sh funcNumber:(int)fn
{
	AddInValue *tab_aiv1 ;
	AddInValue *values ;
	REAL	*input,*output ;
	int	input_OK = TRUE ;
	int	output_OK = TRUE ;
	int	i,j ;
	int	error ;
	int	nb1,nb2 ;
	int	err ;

	/* verification du nombre d©arguments */

	if (num != NB_INPUT)
	{
		pushErrorOnStack(stack,badFormulaError);
		return self;
	}

	/* allocation de la memoire pour la table tab_aiv1 */

	tab_aiv1 = (AddInValue *)calloc(NB_INPUT,sizeof(AddInValue)) ;
	if (!tab_aiv1)
	{
		pushErrorOnStack(stack,badFormulaError);
		return self;
	}

	values = (AddInValue *)calloc(NB_INPUT,sizeof(AddInValue)) ;
	if (!values)
	{
		free(tab_aiv1) ;
		pushErrorOnStack(stack,badFormulaError);
		return self;
	}

	/* initialisation des structures AddInValue */

	for (i = 0 ; i < NB_INPUT ; i++)
	{
		initAddInValue(&tab_aiv1[i]) ;
		initAddInValue(&values[i]) ;
	}

	/* lecture des valeurs d©entrees dans l©ordre inverse */

	for (i = NB_INPUT - 1 ; i >= 0 ; i--)
	{
		popValueFromStack(stack,&tab_aiv1[i]) ;
		getAddInValue(&tab_aiv1[i],&values[i],&error) ;
		input_OK = input_OK && !error ;
	}

	/* renvoie d©un message d©erreur en cas de pbs
	   et liberation de la memoire */


	if (!input_OK)
	{
		fprintf(stderr,"erreur lors de la reccuperation des input\n") ;

		pushErrorOnStack(stack,badFormulaError);

		for (i = 0 ; i < NB_INPUT ; i++)
		{
			freeAddInValue(&tab_aiv1[i]) ;
			freeAddInValue(&values[i]) ;
		}

		free(tab_aiv1) ;
		free(values) ;
		return self;
	}


	/* allocation de la memoire pour les tables input et output */

	input = (REAL *)calloc(NB_INPUT,sizeof(REAL)) ;
	if (!input)
	{
		pushErrorOnStack(stack,badFormulaError);

		for (i = 0 ; i < NB_INPUT ; i++)
		{
			freeAddInValue(&tab_aiv1[i]) ;
			freeAddInValue(&values[i]) ;
		}

		free(tab_aiv1) ;
		free(values) ;

		return self;
	}

	output = (REAL *)calloc(NB_OUTPUT,sizeof(REAL)) ;
	if (!output)
	{
		pushErrorOnStack(stack,badFormulaError);

		for (i = 0 ; i < NB_INPUT ; i++)
		{
			freeAddInValue(&tab_aiv1[i]) ;
			freeAddInValue(&values[i]) ;
		}

		free(tab_aiv1) ;
		free(values) ;

		free(input) ;

		return self;
	}

	/* extraction des donnees dans la table input */

	for ( i = 0 ; i < NB_INPUT ; i++)
	{

		input[i] = getAddInValueNumber(&values[i],&error) ;

		freeAddInValue(&tab_aiv1[i]) ;
		freeAddInValue(&values[i]) ;
	}

	free(tab_aiv1) ;
	free(values) ;

	/* execution d©une propagation */

	run(&net,input,output,stats_input,stats_output) ;

	if (fn < NB_OUTPUT)
	{
		pushNumberOnStack(stack,output[fn]) ;
	}
	else
	{
		pushErrorOnStack(stack,badFormulaError);
	}

	free(input) ;
	free(output) ;

	return self ;
}